#pragma once
#include <string>
#include <functional>
#include <vector>
#include <map>
#include <iostream>
#include "Var.h"
#define Contact(ClassType)  L##ClassType

namespace BlueprintScriptLibrary
{
    class IVariableEntity : public Object
    {
    public:
        class Class* GetClass() { return nullptr; }
        std::string ContainerType;
        std::string name;
    };
    class SingleVaribleEntity : public IVariableEntity
    {
    public:
        SingleVaribleEntity() :IVariableEntity() { ContainerType = "single"; }
        ~SingleVaribleEntity() {
        }
        Class* GetClass();
        Var* Get() { return data; }
        //void Set(Object* Data) { data = Data; }
        Var* data{ nullptr };
        std::string varType;
    };
    class ArrayVaribleEntity :public  IVariableEntity
    {
    public:
        ArrayVaribleEntity() :IVariableEntity() { ContainerType = "array"; }
        Var* Get(VarBaseInt index) { return vctData[index.val]; }
        void Add(Var* Data) { vctData.push_back(Data); }
        VarBaseInt Find(Var* data) {
            for (int i = 0;i < vctData.size();i++)
            {
                if (vctData[i] == data)
                {
                    return i;
                }
            }
            return -1;
        }
        Class* GetClass();
        std::vector< Var*> vctData;
        std::string varType;
    };
    class MapVaribleEntity :public  IVariableEntity
    {
    public:
        MapVaribleEntity() :IVariableEntity() { ContainerType = "map"; }
        Class* GetClass();
        void Add(Var* k, Var* v) {
            mpData[k] = v;
        }
        void Remove(Var* k, Var* v) {
            mpData[k] = v;
        }
        Var* Find(Var* k) {
            if (mpData.find(k) != mpData.end())
            {
                return mpData[k];
            }
            return nullptr;
        }
        // void Set(Var* Data) { vctData.push_back(Data); }
        std::map<Var*, Var*> mpData;
        std::string keyType;
        std::string valType;
    };
}
